#include "TP_FT3168.h"

TP_FT3168::TP_FT3168() : _inited(false) {}

TP_FT3168::~TP_FT3168() {}

bool TP_FT3168::_writeReg(uint8_t reg, uint8_t data)
{
  // _data_buffer[0] = reg;
  // _data_buffer[1] = data;

  _cfg.i2c_wire->beginTransmission(_cfg.dev_addr);
  _cfg.i2c_wire->write(reg);
  _cfg.i2c_wire->write(data);
  if (_cfg.i2c_wire->endTransmission() == 0)
    return true;
  return false;
}

// bool UNIT_SCALES::writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer,
//                              uint8_t length)
// {
//   _wire->beginTransmission(addr);
//   _wire->write(reg);
//   _wire->write(buffer, length);
//   if (_wire->endTransmission() == 0)
//     return true;
//   return false;
// }

void TP_FT3168::_readReg(uint8_t reg, uint8_t readSize)
{
  _cfg.i2c_wire->beginTransmission(_cfg.dev_addr);
  _cfg.i2c_wire->write(reg);
  _cfg.i2c_wire->endTransmission(false);
  _cfg.i2c_wire->requestFrom(_cfg.dev_addr, readSize);
  for (int i = 0; i < readSize; i++)
  {
    _data_buffer[i] = _cfg.i2c_wire->read();
  }
}

void TP_FT3168::_initSetup()
{
  _writeReg(0x86, 0x00); // 关闭监视器模式
  // _writeReg(0x80, 0x7D); // 触摸阈值
  // _writrReg(0x80, 0x7D);
  _writeReg(0x80, 0x01);
  // _writrReg(0x80, 0xBB);

  // ID_G_PERIODACTIVE -> sampling rate
  // 默认 0x08, 最小0x04, 最大0x14
  // _writrReg(0x88, 0x14);
  _writeReg(0x88, 0x14);
  // ESP_LOGI(TAG, "ID_G_PERIODACTIVE, %d", _data_buffer[0]);
  _writeReg(0xBC,0x04);
  // delay(100);
  // _writeReg(0xBC,0x01);
}

// void TP_FT3168::config(const Config_t &cfg)
// {
//   _cfg = cfg;
// }

void TP_FT3168::setPin(int sda, int scl, int rst, int intr)
{
  _cfg.pin_sda = sda;
  _cfg.pin_scl = scl;
  _cfg.pin_rst = rst;
  _cfg.pin_int = intr;
}

bool TP_FT3168::init(int sda, int scl, int rst, int intr, bool initI2C, uint32_t speed)
{
  if (_inited)
  {
    return true;
  }

  _cfg.clk_speed = speed;
  setPin(sda, scl, rst, intr);

  if (initI2C)
  {
    Wire.begin(_cfg.pin_sda, _cfg.pin_scl);
    _cfg.i2c_wire = &Wire;
  }

  gpioInit();
  _initSetup();

  Serial.println("Init success");
  _inited = true;
  return true;
}

void TP_FT3168::gpioInit()
{
  Serial.println("Setup GPIO");

  if (_cfg.pin_int > 0)
  {
    pinMode(_cfg.pin_int, INPUT_PULLUP);
  }

  if (_cfg.pin_rst > 0)
  {
    pinMode(_cfg.pin_rst, OUTPUT);
    digitalWrite(_cfg.pin_rst, LOW);
    delay(10);
    digitalWrite(_cfg.pin_rst, HIGH);
    delay(10);
  }
}
// bool TP_FT3168::init(bool initI2C) {
//   if (_inited) {
//     return true;
//   }

//   if (initI2C) {
//     Wire.begin(_cfg.pin_sda, _cfg.pin_scl);
//     _cfg.i2c_wire = &Wire;
//   }

//   gpioInit();
//   _initSetup();

//   Serial.println("Init success");
//   _inited = true;
//   return true;
// }

bool TP_FT3168::isTouched()
{
  // if (_cfg.pin_int > 0)
  // {
  //   return (digitalRead(_cfg.pin_int) == LOW);
  // }
  _readReg(0x00, 7);
  return (_data_buffer[2] != 0x00);
}

void TP_FT3168::getTouchRaw(TouchPoint_t &tp)
{
  tp.x = -1;
  tp.y = -1;

  // if (_cfg.pin_int > 0 && digitalRead(_cfg.pin_int) != LOW)
  // {
  //   return;
  // }

  _readReg(0x00, 7);
  if (_data_buffer[2] != 0x00)
  {
    tp.event = (_data_buffer[3] >> 6) & 0x03;
    auto x =(int32_t) ((_data_buffer[3] & 0x0F) << 8) | _data_buffer[4];
    tp.id = (_data_buffer[5] >> 4) & 0x0F;
    auto y =(int32_t) ((_data_buffer[5] & 0x0F) << 8) | _data_buffer[6];
    tp.x = y;
    tp.y = 240 - x;
        // tp_x2 = y2;
        // tp_y2 = HEIGHT - x2;
        // Serial.printf("\nTouch X1:%d Y1:%d\n", tp_x1, tp_y1);
        // Serial.printf("Touch X2:%d Y2:%d\n", tp_x2, tp_y2);
  }
}

/*
tp.x 的计算：通过以下操作获取 X 坐标值：

_data_buffer[3] & 0x0F：获取字节索引为 3 的低 4 位，这些位存储了 X 坐标的高 4 位。
(_data_buffer[3] & 0x0F) << 8：将低 4 位左移 8 位，使其位于返回值的高字节位置。
_data_buffer[4]：获取字节索引为 4 的值，这个字节存储了 X 坐标的低 8 位。
将上述两个值相加得到完整的 X 坐标值。
tp.y 的计算：通过以下操作获取 Y 坐标值：

_data_buffer[5] & 0x0F：获取字节索引为 5 的低 4 位，这些位存储了 Y 坐标的高 4 位。
(_data_buffer[5] & 0x0F) << 8：将低 4 位左移 8 位，使其位于返回值的高字节位置。
_data_buffer[6]：获取字节索引为 6 的值，这个字节存储了 Y 坐标的低 8 位。
将上述两个值相加得到完整的 Y 坐标值。

#include <TP_FT3168.h>

TP_FT3168 touchScreen;

void setup() {
  Serial.begin(9600);

  // 配置触摸屏参数
  TP_FT3168::Config_t config;
  config.pin_sda = 21;   // SDA 引脚
  config.pin_scl = 22;   // SCL 引脚
  config.pin_int = 23;   // INT 引脚

  // 初始化触摸屏
  if (touchScreen.init(config)) {
    Serial.println("Touch screen initialized successfully");
  } else {
    Serial.println("Failed to initialize touch screen");
  }
}

void loop() {
  // 获取触摸点数据
  TP_FT3168::TouchPoint_t tp;
  touchScreen.getTouchRaw(tp);

  // 打印触摸点数据
  Serial.print("Event: ");
  Serial.print(tp.event);
  Serial.print(", ID: ");
  Serial.print(tp.id);
  Serial.print(", X: ");
  Serial.print(tp.x);
  Serial.print(", Y: ");
  Serial.println(tp.y);

  delay(100);
}
*/